home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 418_03 / outfile.c < prev    next >
C/C++ Source or Header  |  1994-03-02  |  51KB  |  1,882 lines

  1. /* outfile.c
  2.  * RasMol2 Molecular Graphics
  3.  * Roger Sayle, February 1994
  4.  * Version 2.3
  5.  */
  6. #define OUTFILE
  7. #include "rasmol.h"
  8.  
  9. #ifdef IBMPC
  10. #include <windows.h>
  11. #include <malloc.h>
  12. #endif
  13. #ifndef sun386
  14. #include <stdlib.h>
  15. #endif
  16.  
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <math.h>
  20.  
  21. #include "outfile.h"
  22. #include "molecule.h"
  23. #include "command.h"
  24. #include "transfor.h"
  25. #include "render.h"
  26. #include "graphics.h"
  27. #include "pixutils.h"
  28.  
  29.  
  30. #ifdef EIGHTBIT
  31. #define RComp(x)   (RLut[LutInv[x]])
  32. #define GComp(x)   (GLut[LutInv[x]])
  33. #define BComp(x)   (BLut[LutInv[x]])
  34. #else
  35. #define RComp(x)   (((x)>>16)&0xff)
  36. #define GComp(x)   (((x)>>8)&0xff)
  37. #define BComp(x)   ((x)&0xff)
  38. #endif
  39.  
  40.  
  41. /* Sun rasterfile.h macro defns */
  42. #define RAS_MAGIC       0x59a66a95
  43. #define RAS_RLE         0x80
  44. #define RT_STANDARD     1
  45. #define RT_BYTE_ENCODED 2
  46. #define RMT_NONE        0
  47. #define RMT_EQUAL_RGB   1
  48.  
  49. /* Standard A4 size page: 8.267x11.811 inches */
  50. /* U.S. Normal size page: 8.500x11.000 inches */
  51. #define PAGEHIGH  (11.811*72.0)
  52. #define PAGEWIDE  (8.267*72.0)
  53. #define BORDER    0.90
  54.  
  55. /* Compression Ratio   0<x<127 */
  56. #define EPSFCompRatio  32
  57.  
  58. #define Round(x)  ((int)(x))
  59. #define Rad2Deg   (180.0/PI)
  60. #define Deg2Rad   (PI/180.0)
  61.  
  62.  
  63. #define PSLine    0x00
  64. #define PSStick   0x01
  65. #define PSSphere  0x02
  66.  
  67. typedef void __far* PSItemPtr;
  68.  
  69.  
  70. #ifdef IBMPC
  71. static short __far *ABranch;
  72. static short __far *DBranch;
  73. static short __far *Hash;
  74. static Byte __far *Node;
  75. #else
  76. static short ABranch[4096];
  77. static short DBranch[4096];
  78. static short Hash[256];
  79. static Byte Node[4096];
  80. #endif
  81.  
  82.  
  83. typedef struct {
  84.     Byte len;
  85.     Byte ch;
  86.         } BMPPacket;
  87.         
  88.  
  89. static BMPPacket BMPBuffer[10];
  90. static int BMPCount,BMPTotal;        
  91. static int BMPPad;
  92.  
  93. static int GIFClrCode; 
  94. static int GIFEOFCode;
  95.  
  96. static Card RLEFileSize;
  97. static int RLEEncode;
  98. static int RLEOutput;
  99. static int RLELength;
  100. static int RLEPixel;
  101. static int RLEChar;
  102.  
  103.  
  104. static Byte Buffer[256];
  105. static Byte LutInv[256];
  106. static int LineLength;
  107. static FILE *OutFile;
  108. static Card BitBuffer;
  109. static int BitBufLen;
  110. static int PacketLen;
  111. static int CodeSize;
  112.  
  113. static Real LineWidth;
  114. static int VectSolid;
  115. static int VectCol;
  116.  
  117. /* Macros for commonly used loops */
  118. #define ForEachAtom  for(chain=Database->clist;chain;chain=chain->cnext) \
  119.                      for(group=chain->glist;group;group=group->gnext)    \
  120.                      for(aptr=group->alist;aptr;aptr=aptr->anext)
  121. #define ForEachBond  for(bptr=Database->blist;bptr;bptr=bptr->bnext)
  122. #define ForEachBack  for(chain=Database->clist;chain;chain=chain->cnext) \
  123.                      for(bptr=chain->blist;bptr;bptr=bptr->bnext)
  124.  
  125.  
  126.  
  127. static void FatalOutputError( ptr )
  128.     char *ptr;
  129. {
  130.     if( CommandActive ) WriteChar('\n');
  131.     WriteString("Output Error: Unable to create file `");
  132.     WriteString( ptr );  WriteString("'!\n");
  133.     CommandActive = False;
  134. }
  135.  
  136.  
  137.  
  138. static void WritePPMWord( i )
  139.     int i;
  140. {
  141.     if( i>99 )
  142.     {   fputc((i/100)+'0',OutFile); i %= 100;
  143.         fputc((i/10) +'0',OutFile); i %= 10;
  144.     } else if( i>9 )
  145.     {   fputc((i/10)+'0',OutFile);  i %= 10;
  146.     }
  147.     putc(i+'0',OutFile);
  148. }
  149.  
  150.  
  151. int WritePPMFile( name, raw )
  152.     char *name;  int raw;
  153. {
  154.     register Pixel __huge *ptr;
  155.     register int i, c;
  156.     register int x,y;
  157.  
  158. #ifdef IBMPC
  159.     OutFile = fopen(name, (raw?"wb":"w") );
  160. #else
  161.     OutFile = fopen(name,"w");
  162. #endif
  163.  
  164.     if( !OutFile ) 
  165.     {   FatalOutputError(name);
  166.         return( False );
  167.     }
  168.     fputc('P',OutFile); fputc((raw?'6':'3'),OutFile);
  169.     fprintf(OutFile," %d %d 255\n",XRange,YRange);
  170.  
  171. #ifdef EIGHTBIT
  172.     for( i=0; i<256; i++ )
  173.         if( ULut[i] )
  174.             LutInv[Lut[i]] = i;
  175. #endif
  176.  
  177. #ifdef IBMPC
  178.     FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);
  179. #endif
  180.  
  181. #ifndef INVERT
  182.     ptr = FBuffer;
  183. #endif
  184.  
  185.     c = 0;
  186.  
  187.     if( !raw )
  188.     {   c = 0;
  189.         for( y=YRange-1; y>=0; y-- )
  190.         {
  191. #ifdef INVERT
  192.             ptr = FBuffer + (Long)y*XRange;
  193. #endif
  194.             for( x=0; x<XRange; x++ )
  195.             {   i = *ptr++; c++;
  196.                 WritePPMWord((int)RComp(i));  fputc(' ',OutFile);
  197.                 WritePPMWord((int)GComp(i));  fputc(' ',OutFile);
  198.                 WritePPMWord((int)BComp(i));  
  199.                 if( c==5 )
  200.                 { c=0; fputc('\n',OutFile);
  201.                 } else fputc(' ',OutFile);
  202.             }
  203.         }
  204.     } else
  205.         for( y=YRange-1; y>=0; y-- )
  206.         {
  207. #ifdef INVERT
  208.             ptr = FBuffer + (Long)y*XRange;
  209. #endif
  210.             for( x=0; x<XRange; x++ )
  211.             {   i = *ptr++;
  212.                 fputc((int)RComp(i),OutFile);
  213.                 fputc((int)GComp(i),OutFile);
  214.                 fputc((int)BComp(i),OutFile);
  215.             }
  216.         }
  217.  
  218.     fclose(OutFile);
  219. #ifdef IBMPC
  220.     GlobalUnlock(FBufHandle); 
  221. #endif
  222.     return( True );
  223. }
  224.  
  225.  
  226.  
  227. #ifdef EIGHTBIT
  228. static int CompactColourMap()
  229. {
  230.     register Pixel __huge *ptr;
  231.     register Long pos, count;
  232.     register int i, cols;
  233.  
  234.     for( i=0; i<256; i++ )
  235.     {   if( ULut[i] )
  236.             LutInv[Lut[i]] = i;
  237.         Buffer[i] = 0;
  238.         Node[i] = 5;
  239.     }
  240.  
  241. #ifdef IBMPC
  242.     ptr = (Pixel __huge*)GlobalLock(FBufHandle);    
  243. #else
  244.     ptr = FBuffer;
  245. #endif
  246.  
  247.     cols = 0;
  248.     count = (Long)XRange*YRange;
  249.     for( pos=0; pos<count; pos++ )
  250.     {   i = LutInv[*ptr++];
  251.         if( !Buffer[i] ) 
  252.         {   Node[cols++] = i;
  253.             Buffer[i] = cols;
  254.         }
  255.     }
  256.  
  257.     for( i=0; i<256; i++ )
  258.         LutInv[i] = Buffer[LutInv[i]]-1;
  259. #ifdef IBMPC
  260.     GlobalUnlock(FBufHandle);
  261. #endif
  262.     return( cols );
  263. }
  264. #endif
  265.  
  266.  
  267.  
  268. static void WriteGIFCode( code )
  269.     int code;
  270. {
  271.     register int max;
  272.  
  273.     max = (code==GIFEOFCode)? 0 : 7;
  274.     BitBuffer |= ((Card)code<<BitBufLen);
  275.     BitBufLen += CodeSize;
  276.  
  277.     while( BitBufLen > max )
  278.     {    
  279. #ifdef IBMPC
  280.          Buffer[PacketLen++]=(Byte)(BitBuffer&0xff);
  281. #else
  282.          Buffer[PacketLen++]=BitBuffer;
  283. #endif
  284.          BitBuffer >>= 8;
  285.          BitBufLen -= 8;
  286.  
  287.         if( PacketLen==255 )
  288.         {   fputc(0xff,OutFile);
  289.             fwrite((char*)Buffer,1,255,OutFile);
  290.             PacketLen = 0;
  291.         }
  292.     }
  293. }
  294.  
  295. int WriteGIFFile( name )
  296.     char *name;
  297. {
  298.     register int i,j,cols;
  299.     register int pref,next,last;
  300.     register int isize, ilast;
  301.     register Pixel __huge *ptr;
  302.     register short __far *prev;
  303.     register int x,y,init;
  304.  
  305. #ifdef EIGHTBIT
  306.     cols = CompactColourMap();
  307.     if( cols<2 ) return( False );
  308.  
  309.     for( isize=0; isize<8; isize++ )
  310.         if( (1<<isize)>=cols ) break;
  311.     cols = 1<<isize;
  312.  
  313. #ifdef IBMPC
  314.     OutFile = fopen(name,"wb");
  315. #else
  316.     OutFile = fopen(name,"w");
  317. #endif
  318.     if( !OutFile ) 
  319.     {    FatalOutputError(name);
  320.          return( False );
  321.     }
  322.     fwrite("GIF87a",1,6,OutFile);
  323.     fputc(XRange&0xff,OutFile);  fputc((XRange>>8)&0xff,OutFile);
  324.     fputc(YRange&0xff,OutFile);  fputc((YRange>>8)&0xff,OutFile);
  325.     fputc(0xf0|(isize-1),OutFile); 
  326.     fputc(0x00,OutFile); 
  327.     fputc(0x00,OutFile);
  328.  
  329.     for( j=0; j<cols; j++ )
  330.     {   i = Node[j];
  331.         fputc((int)RLut[i],OutFile);
  332.         fputc((int)GLut[i],OutFile);
  333.         fputc((int)BLut[i],OutFile);
  334.     }
  335.  
  336.     fputc(',',OutFile);
  337.     fputc(0x00,OutFile);  fputc(0x00,OutFile);
  338.     fputc(0x00,OutFile);  fputc(0x00,OutFile);
  339.     fputc(XRange&0xff,OutFile);  fputc((XRange>>8)&0xff,OutFile);
  340.     fputc(YRange&0xff,OutFile);  fputc((YRange>>8)&0xff,OutFile);
  341.     fputc(0x00,OutFile);  fputc(isize,OutFile);
  342.  
  343.     PacketLen=0;
  344.     BitBuffer=0;
  345.     BitBufLen=0;
  346.  
  347.     GIFClrCode = (1<<isize);
  348.     GIFEOFCode = GIFClrCode+1;
  349.     ilast = (GIFClrCode<<1)-GIFEOFCode;
  350.     isize++;
  351.  
  352.     CodeSize = isize;
  353.     last = ilast;
  354.     next = 1;  
  355.    
  356.     WriteGIFCode(GIFClrCode);
  357.     for( i=0; i<cols; i++ )
  358.         Hash[i]=0;
  359.  
  360. #ifdef IBMPC
  361.     FBuffer = (Pixel __huge*)GlobalLock(FBufHandle);    
  362. #endif
  363.  
  364. #ifndef INVERT
  365.     ptr = FBuffer;
  366. #endif
  367.  
  368.     /* Avoid Warnings! */
  369.     prev = (short __far*)0; 
  370.     pref = 0;
  371.  
  372.     ini